#include <iostream>

using namespace std;

#define PI 3.14
/*
    宏的缺点:
        1). #define 是不被视为语言的一部分，它在程序编译阶段中的预处理阶段的作用，就是做简单的替换.\
        2). 程序编译在预处理阶段后，才进行真正的编译阶段。在有的编译器，运用了此 PI 常量，如果遇到了编译错误，那么这个错误信息也许会提到 3.14 而不是 PI
*/

// 使用const、enum、inline代替宏
// 1. const替换：
//      const有作用域，而#define没有。这可以防止命名冲突。
//      const能被调试器识别，而#define不能。
const double Pi = 3.14;                // 定义一个int类型的常量，可以解决
const char *const ptr = "hello world"; // 定义常量字符串，则必须要 const 两次，目的是为了防止指针所指内容和指针自身不能被改变
const std::string myName("hello world");

// 2. enum 替换:
//          无法利用 #define 创建一个 class 专属常量，因为 #define 并不重视作用域。
class GamePlayer
{
private:
    static const int DNumTurns = 5; // VC编译器不支持这种行为：不允许static成员在声明式中获取初值，数组在编译的时候必须指定大小，就用enum
    enum
    {
        ENumTurns = 5
    };
    int scores[ENumTurns];
    int scores[DNumTurns]; // 这里在声明数组的时候
};

// 3. inline代替宏
//        和宏一样，内联函数在调用的地方展开，没有函数压栈的开销，提升了程序的执行效率。而且比起宏，内联函数不会因为运算符的优先级而导致程序出错。
//         #define定义的宏不能进行类型检查，而inline函数可以
#define Max(a, b) (((a) * (b) == 8) ? ((a) * (b)) : (b))

inline int max(int a, int b)
{
    if (a * b == 8)
    {
        return a * b;
    }
    else
    {
        return b;
    }
}

int main()
{
    return 0;
}